#pragma once

#include <iostream>
#include <functional>

#include "Inetaddr.hpp"
// #include "log.hpp"
#include "protocol.hpp"
#include "connection.hpp"
#include "NetCal.hpp"

// using namespace log_namespace;

class IOService
{
public:
    void IOexecute(myConnection* conn)
    {
        while (true)
        {
            // 1. 负荷读取

            // 2. 报文解析
            std::string package = Decode(conn->getinBuffer());
            if (package.empty())
            {
                break;
            }
            // 走到这一行，package一定是一个完整的报文
            // 这里要实现的是计算器的业务逻辑
            // 所以下面这句话只是创建一个能够处理
            // 数据从客户端应用层到服务器端应用层的各种行为的对象
            auto req = Factory::buildRequest();
            std::cout << "package: \n" << package << std::endl;

            // 3. 反序列化
            req->Deserialize(package);

            // 4. 业务处理
            // auto resp = _process(req); // 通过请求，得到应答
            auto resp = _cal.calculator(req);

            // 5. 构建序列化应答
            std::string respjson;
            resp->Serialize(&respjson);
            std::cout << "respjson: \n" << respjson << std::endl;

            // 6. 添加len长度报头
            respjson = Encode(respjson);
            std::cout << "respjson add header done: \n" << respjson << std::endl;

            // 7. 将数据发回去
            conn->appendOutBuffer(respjson);
        }

        if (!conn->getoutBuffer().empty())
        {
            // 我们至少处理了一个请求，同时至少会有一个应答
            // conn->_handler_sender(conn); // met1: 直接发送数据
            conn->_R->EnableConnectiontforReadandWrite(conn->getsocketfd(), true, true);
        }
    }
private:
    NetCal _cal;
};
